﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Authorization.Properties;

namespace Authorization
{
    partial class AuthorizationServiceBase
    {

        #region RoleDefinitions Members


        public RoleDefinitionCollection GetAllRoleDefinitions(string applicationName, string scopeName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");

            var application = AuthorizationStoreManager.GetApplication(applicationName);
            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.GetAllRoleDefinitions", Resources.invalid_application);
            }
            return application.GetRoleDefinitions(scopeName);
        }

        public string[] GetAllRoleDefinitionNames(string applicationName, string scopeName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");

            var app = AuthorizationStoreManager.GetApplication(applicationName);

            if (app == null)
            {
                throw new AuthorizationException("AuthorizationService.GetAllRoleDefinitionNames", Resources.invalid_application);
            }

            return app.GetRoleDefinitionNames(scopeName);
        }

        public RoleDefinition GetRoleDefinition(string applicationName, string scopeName, string roleDefinitionName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref roleDefinitionName, true, true, false, 64, "roleDefinitionName");

            var app = AuthorizationStoreManager.GetApplication(applicationName);

            if (app == null)
            {
                throw new AuthorizationException("AuthorizationService.GetRoleDefinition", Resources.invalid_application);
            }

            var roleDefinition = app.GetRoleDefinition(roleDefinitionName, scopeName);

            if (roleDefinition != null)
            {
                return roleDefinition;
            }
            else
                throw new AuthorizationException("AuthorizationService.GetRoleDefinition", Resources.roledefinition_not_found);
        }

        public bool RoleDefinitionExists(string applicationName, string scopeName, string roleDefinitionName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref roleDefinitionName, true, true, false, 64, "roleDefinitionName");

            var app = AuthorizationStoreManager.GetApplication(applicationName);

            if (app == null)
            {
                throw new AuthorizationException("AuthorizationService.RoleDefinitionExists", Resources.invalid_application);
            }

            return app.RoleDefinitionExists(roleDefinitionName, scopeName);
        }

        public RoleDefinition CreateRoleDefinition(string applicationName, string scopeName, string roleDefinitionName, string description)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref roleDefinitionName, true, true, false, 64, "roleDefinitionName");

            Application application = AuthorizationStoreManager.GetApplication(applicationName);

            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.CreateRoleDefinition", Resources.invalid_application);
            }

            var role = application.CreateRoleDefinition(roleDefinitionName, description, scopeName);
            role.Save();
            return role;
        }

        public void DeleteRoleDefinition(string applicationName, string scopeName, string roleDefinitionName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref roleDefinitionName, true, true, false, 64, "roleDefinitionName");

            var application = AuthorizationStoreManager.GetApplication(applicationName);

            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.DeleteRoleDefinition", Resources.invalid_application);
            }

            application.DeleteRoleDefinition(roleDefinitionName, scopeName);
            application.Save();
        }

        public void UpdateRoleDefinition(string applicationName, string scopeName, string roleDefinitionName, string newRoleDefinitionName, string newDescription)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref roleDefinitionName, true, true, false, 64, "roleDefinitionName");
            SecUtility.CheckParameter(ref newRoleDefinitionName, true, true, false, 64, "newRoleDefinitionName");

            var application = AuthorizationStoreManager.GetApplication(applicationName);

            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.UpdateRoleDefinition", Resources.invalid_application);
            }

            var role = application.UpdateRoleDefinition(roleDefinitionName, scopeName, newRoleDefinitionName, newDescription);
            role.Save();
        }


        //TODO: ADICIONAR NOVOS METODOS PARA ADICIONAR ROLES/TASKS/OPERATIONS
        public RoleAssignmentCollection GetRoleAssignments(string applicationName, string scopeName, string roleDefinitionName, string scopeNameToSearch, bool isRecursive)
        {
            var roleDefinition = GetRoleDefinition(applicationName, scopeName, roleDefinitionName);
            return roleDefinition.GetRoleAssignments(scopeNameToSearch, isRecursive);
        }

        public string[] GetRoleDefinitionNamesInRoleDefinition(string applicationName, string scopeName, string roleDefinitionName)
        {
            return GetRoleDefinition(applicationName, scopeName, roleDefinitionName).GetRoleDefinitionNames();
        }

        public RoleDefinitionCollection GetRoleDefinitionInRoleDefinition(string applicationName, string scopeName, string roleDefinitionName)
        {
            return GetRoleDefinition(applicationName, scopeName, roleDefinitionName).GetRoleDefinitions();
        }

        public void RemoveRoleDefinitionFromRoleDefinition(string applicationName, string scopeName, string parentRoleDefinitionName, string childRoleDefinitionName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref parentRoleDefinitionName, true, true, false, 64, "parentRoleDefinitionName");
            SecUtility.CheckParameter(ref childRoleDefinitionName, true, true, false, 64, "childRoleDefinitionName");

            var roleDefinition = GetRoleDefinition(applicationName, scopeName, parentRoleDefinitionName);
            if (roleDefinition != null)
            {
                roleDefinition.RemoveRoleDefinition(childRoleDefinitionName);
                roleDefinition.Save();
            }
        }

        public void AddRoleDefinitionToRoleDefinition(string applicationName, string parentScopeName, string parentRoleDefinitionName, string childRoleDefinitionName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref parentRoleDefinitionName, true, true, false, 64, "parentRoleDefinitionName");
            SecUtility.CheckParameter(ref childRoleDefinitionName, true, true, false, 64, "childRoleDefinitionName");

            var roleDefinition = GetRoleDefinition(applicationName, parentScopeName, parentRoleDefinitionName);

            if (roleDefinition != null)
            {
                roleDefinition.AddRoleDefinition(childRoleDefinitionName);
                roleDefinition.Save();
            }
        }

        public string[] GetTaskNamesInRoleDefinition(string applicationName, string scopeName, string roleDefinitionName)
        {
            var roleDefinition = GetRoleDefinition(applicationName, scopeName, roleDefinitionName);
            return roleDefinition.GetTaskNames();
        }

        public TaskCollection GetTasksInRoleDefinition(string applicationName, string scopeName, string roleDefinitionName)
        {
            var roleDefinition = GetRoleDefinition(applicationName, scopeName, roleDefinitionName);
            return roleDefinition.GetTasks();
        }

        public string[] GetOperationNamesInRoleDefinition(string applicationName, string scopeName, string roleDefinitionName)
        {

            var roleDefinition = GetRoleDefinition(applicationName, scopeName, roleDefinitionName);
            return roleDefinition.GetOperationNames();
        }

        public OperationCollection GetOperationsInRoleDefinition(string applicationName, string scopeName, string roleDefinitionName)
        {
            var roleDefinition = GetRoleDefinition(applicationName, scopeName, roleDefinitionName);

            return roleDefinition.GetOperations();
        }

        public void AddOperationToRoleDefinition(string applicationName, string scopeName, string roleDefinitionName, string operationName)
        {
            SecUtility.CheckParameter(ref operationName, true, true, false, 64, "operationName");

            var roleDefinition = GetRoleDefinition(applicationName, scopeName, roleDefinitionName);

            if (roleDefinition != null)
            {
                roleDefinition.AddOperation(operationName);
                roleDefinition.Save();
            }
        }

        public void RemoveOperationFromRoleDefinition(string applicationName, string scopeName, string roleDefinitionName, string operationName)
        {

            SecUtility.CheckParameter(ref operationName, true, true, false, 64, "operationName");

            var roleDefinition = GetRoleDefinition(applicationName, scopeName, roleDefinitionName);

            if (roleDefinition != null)
            {
                roleDefinition.RemoveOperation(operationName);
                roleDefinition.Save();
            }
        }

        public void RemoveTaskFromRoleDefinition(string applicationName, string scopeName, string roleDefinitionName, string childTaskName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref roleDefinitionName, true, true, false, 64, "roleDefinitionName");
            SecUtility.CheckParameter(ref childTaskName, true, true, false, 64, "childTaskName");
            var roleDefinition = GetRoleDefinition(applicationName, scopeName, roleDefinitionName);

            if (roleDefinition != null)
            {
                roleDefinition.RemoveTask(childTaskName);
                roleDefinition.Save();
            }
        }

        public void AddTaskToRoleDefinition(string applicationName, string parentScopeName, string roleDefinitionName, string childTaskName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref roleDefinitionName, true, true, false, 64, "roleDefinitionName");
            SecUtility.CheckParameter(ref childTaskName, true, true, false, 64, "childTaskName");

            var roleDefinition = GetRoleDefinition(applicationName, parentScopeName, roleDefinitionName);

            if (roleDefinition != null)
            {
                roleDefinition.AddTask(childTaskName);
                roleDefinition.Save();
            }
        }


        #endregion

    }
}
